
#![allow(unused_variables)]
#![allow(dead_code)]

use crate::prequire::{
  adb::{shell::ShellCmd, start_app},
  BinaryCommand,
};
use crate::project::conf::project_conf::ProjectConf;
use crate::project::{Project, CaptureScenes};
use anyhow::{anyhow, Result};
use std::path::{Path, PathBuf};
use indicatif::{MultiProgress, ProgressStyle};
use std::fs::create_dir_all;

mod mtt;

use mtt::keyword_search_result::KeywordSearchResultParser;


pub struct ParseOptions {
  // out_dir: PathBuf,
  // num: u64,
  train: bool,
  preprocess: bool,
  scene: CaptureScenes,
  exts: Vec<&'static str>,
}

impl ParseOptions {
  pub fn new() -> Self {
    ParseOptions {
      // out_dir: PathBuf::new(),
      // num: 1,
      train: false,
      preprocess: false,
      scene: CaptureScenes::None,
      exts: vec!["png"],
    }
  }
  // pub fn set_out_dir<P: AsRef<Path>>(&mut self, out_dir: P) -> &mut Self {
  //   self.out_dir.clear();
  //   self.out_dir.push(out_dir.as_ref());
  //   self
  // }
  // pub fn set_num(&mut self, num: u64) -> &mut Self {
  //   self.num = num;
  //   self
  // }
  pub fn set_train(&mut self, train: bool) -> &mut Self {
    self.train = train;
    self
  }
  pub fn set_preprocess(&mut self, preprocess: bool) -> &mut Self {
    self.preprocess = preprocess;
    self
  }
  pub fn set_scene(&mut self, scene: CaptureScenes) -> &mut Self {
    self.scene = scene;
    self
  }
  pub fn set_exts(&mut self, exts: Vec<&'static str>) -> &mut Self {
    self.exts = exts;
    self
  }
  pub fn parse<P1: AsRef<Path>, P2: AsRef<Path>>(
    &self,
    conf: &ProjectConf,
    input_dir: P1,
    out_dir: P2,
  ) -> Result<Vec<String>> {
    match self.scene {
      CaptureScenes::Keyword => {
        println!("input_dir=>{}", input_dir.as_ref().display());
        println!("out_dir=>{}", out_dir.as_ref().display());
        KeywordSearchResultParser::new(conf).parse(input_dir, out_dir, &self)
      },
      _ => Err(anyhow!("场景{:?}没有实现parser", self.scene)),
    }
  }
}

pub trait Parser {
  fn parse<P1: AsRef<Path>, P2: AsRef<Path>>(
    &self,
    input_dir: P1,
    out_dir: P2,
    opts: &ParseOptions,
  ) -> Result<Vec<String>> {
    Err(anyhow!("not impl for parse"))
  }
  
  fn ensure_out_dir(&self, out_dir: &Path) {
    println!("ensure_out_dir<{}>", out_dir.display());
    create_dir_all(out_dir).expect("create_dir_all fail!");
  }

  fn ensure_out_raw_dir(&self, out_dir: &Path) -> PathBuf {
    println!("ensure_raw_dir<{}/raw>", out_dir.display());
    let out_raw_path = out_dir.join("raw");
    create_dir_all(&out_raw_path).expect("create_dir_all fail!");
    out_raw_path
  }

  fn create_indicator(&self) -> (MultiProgress, ProgressStyle) {
    let m = MultiProgress::new();
    let sty =
      ProgressStyle::with_template("[{elapsed_precise}] {bar:40.cyan/blue} {pos:>7}/{len:7} {msg}")
        .unwrap()
        .progress_chars("##-");

    (m, sty)
  }
}